package channel

import (
	"os/exec"
	"path/filepath"

	"gitee.com/extrame/fb-runner/util"
	"github.com/sirupsen/logrus"
)

func Create(base, name string) error {
	// 	## Create channeltx
	util.Mkdir(filepath.Join(base, "channel-artifacts"))
	logrus.Infoln("### Generating channel create transaction '" + name + ".tx' ###")
	err := createChannelTx(base, name)
	if err != nil {
		return err
	}

	// ## Create anchorpeertx
	logrus.Infoln("### Generating anchor peer update transactions ###")
	err = createAncorPeerTx(base, name)
	if err != nil {
		return err
	}

	// FABRIC_CFG_PATH=$PWD/../config/

	// ## Create channel
	logrus.Infoln("Creating channel " + name)
	err = createChannel(base, name)
	if err != nil {
		return err
	}

	// ## Join all the peers to the channel

	err = JoinChannel(base, name)
	if err != nil {
		return err
	}
	// JoinChannel 2

	err = UpdateAnchorPeers(base, name)
	if err != nil {
		return err
	}

	return nil
}

func UpdateAnchorPeers(base, name string) error {

	for k, org := range util.Config.GetPeerOrganizations() {
		logrus.Infoln("Updating anchor peers for " + k)
		var args = []string{"channel", "update", "-c", name, "-f",
			filepath.Join(base, "channel-artifacts/"+org.Msp+"anchors.tx")}
		args = append(args, org.GetConnArgs(base)...)
		cmd := exec.Command("peer", args...)
		util.UseOrg(cmd, base, org, true)
		_, _, err := util.Run(cmd)
		if err != nil {
			return err
		}
	}
	return nil

}

func JoinChannel(base, name string) error {

	for k, org := range util.Config.GetPeerOrganizations() {
		_, err := org.GetLocalPeer()
		if err == nil {
			logrus.Infoln("Join "+k+" peers to the channel", name)
			cmd := exec.Command("peer", "channel", "join", "-b", filepath.Join(base, "channel-artifacts/"+name+".block"))
			util.UseOrg(cmd, base, org, false)
			_, _, err := util.Run(cmd)
			if err != nil {
				return err
			}
		} else {
			logrus.Infoln(k + "没有本地节点")
		}

	}
	return nil

}

func createAncorPeerTx(base, name string) error {
	var cfgDir = filepath.Join(base, "config")
	for _, org := range util.Config.GetPeerOrganizations() {
		cmd := exec.Command("configtxgen", "-configPath", cfgDir, "-profile", "TwoOrgsChannel", "-outputAnchorPeersUpdate", filepath.Join(base, "channel-artifacts/"+org.Msp+"anchors.tx"), "-channelID", name, "-asOrg", org.Msp)
		util.UseOrg(cmd, base, org, false)
		_, _, err := util.Run(cmd)
		if err != nil {
			return err
		}
	}
	return nil
}

func createChannelTx(base, name string) error {
	var cfgDir = filepath.Join(base, "config")
	cmd := exec.Command("configtxgen", "-configPath", cfgDir, "-profile", "TwoOrgsChannel", "-outputCreateChannelTx", filepath.Join(base, "channel-artifacts/"+name+".tx"), "-channelID", name)
	cmd = util.UseOrg(cmd, base, nil, false)
	_, _, err := util.Run(cmd)
	return err
}

func createChannel(base, name string) error {
	cmd := exec.Command("peer", "channel", "create",
		"-c", name, "-f", filepath.Join(base, "channel-artifacts/"+name+".tx"), "--outputBlock", filepath.Join(base, "channel-artifacts/"+name+".block"))
	cmd = util.UseOrg(cmd, base, nil, true)
	_, _, err := util.Run(cmd)
	return err
}
